Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Smart pointer</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Smart_pointer"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Smart_pointer rootpage-Smart_pointer skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Smart pointer</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<style data-mw-deduplicate="TemplateStyles:r1251242444">
/* start https://en.wikipedia.org/ */


.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}


/* end https://en.wikipedia.org/ */
</style>
<p class="mw-empty-elt">

</p><p>In <a href="Computer_science" title="Computer science">computer science</a>, a <b>smart pointer</b> is an <a href="Abstract_data_type" title="Abstract data type">abstract data type</a> that simulates a <a href="Pointer_(computer_programming)" title="Pointer (computer programming)">pointer</a> while providing added features, such as automatic <a href="Memory_management" title="Memory management">memory management</a> or <a href="Bounds_checking" title="Bounds checking">bounds checking</a>. Such features are intended to reduce <a href="Software_bug" title="Software bug">bugs</a> caused by the misuse of pointers, while retaining efficiency. Smart pointers typically keep track of the memory they point to, and may also be used to manage other resources, such as network connections and <a href="File_handle" class="mw-redirect" title="File handle">file handles</a>. Smart pointers were first popularized in the programming language <a href="C%2B%2B" title="C++">C++</a> during the first half of the 1990s as rebuttal to criticisms of C++'s lack of <a href="Automatic_garbage_collection" class="mw-redirect" title="Automatic garbage collection">automatic garbage collection</a>.<sup id="cite_ref-Kline_1997_1-0" class="reference"><a href="#cite_note-Kline_1997-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-Colvin_1994_2-0" class="reference"><a href="#cite_note-Colvin_1994-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p><p>Pointer misuse can be a major source of bugs. Smart pointers prevent most situations of <a href="Memory_leak" title="Memory leak">memory leaks</a> by making the memory deallocation automatic. More generally, they make <a href="Object_destruction" class="mw-redirect" title="Object destruction">object destruction</a> automatic: an object controlled by a smart pointer is automatically destroyed (<a href="Finalization" class="mw-redirect" title="Finalization">finalized</a> and then deallocated) when the last (or only) owner of an object is destroyed, for example because the owner is a <a href="Local_variable" title="Local variable">local variable</a>, and execution leaves the variable's <a href="Scope_(programming)" class="mw-redirect" title="Scope (programming)">scope</a>. Smart pointers also eliminate <a href="Dangling_pointer" title="Dangling pointer">dangling pointers</a> by postponing destruction until an object is no longer in use.
</p><p>If a language supports automatic garbage collection (for example, <a href="Java_(programming_language)" title="Java (programming language)">Java</a> or <a href="C_Sharp_(programming_language)" title="C Sharp (programming language)">C#</a>), then smart pointers are unneeded for reclaiming and safety aspects of memory management, yet are useful for other purposes, such as <a href="Cache_(computing)" title="Cache (computing)">cache</a> data structure residence management and <a href="Resource_management" title="Resource management">resource management</a> of objects such as file handles or <a href="Network_socket" title="Network socket">network sockets</a>.
</p><p>Several types of smart pointers exist. Some work with <a href="Reference_counting" title="Reference counting">reference counting</a>, others by assigning ownership of an object to one pointer.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="History">History</h2></div>
<p>Even though C++ popularized the concept of smart pointers, especially the <a href="Reference_counting" title="Reference counting">reference-counted</a> variety,<sup id="cite_ref-Klabnik-Nichols_2023_3-0" class="reference"><a href="#cite_note-Klabnik-Nichols_2023-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup> the immediate predecessor of one of the languages that inspired C++'s design had reference-counted references built into the language. C++ was inspired in part by <a href="Simula67" class="mw-redirect" title="Simula67">Simula67</a>.<sup id="cite_ref-Stroustrup_4-0" class="reference"><a href="#cite_note-Stroustrup-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup> Simula67's ancestor was <a href="Simula_I" class="mw-redirect" title="Simula I">Simula I</a>. Insofar as Simula I's <i>element</i> is analogous to C++'s pointer without <i>null</i>, and insofar as Simula I's process with a dummy-statement as its activity body is analogous to C++'s <i>struct</i> (which itself is analogous to <a href="C._A._R._Hoare" class="mw-redirect" title="C. A. R. Hoare">C. A. R. Hoare</a>'s <i>record</i> in then-contemporary 1960s work), Simula I had reference counted elements (i.e., pointer-expressions that house indirection) to processes (i.e., records) no later than September 1965, as shown in the quoted paragraphs below.<sup id="cite_ref-Dahl-Nygaard_1966_5-0" class="reference"><a href="#cite_note-Dahl-Nygaard_1966-5"><span class="cite-bracket">[</span>5<span class="cite-bracket">]</span></a></sup>
</p>
<blockquote>
<p>Processes can be referenced individually. Physically, a process reference is a pointer to an area of memory containing the data local to the process and some additional information defining its current state of execution. However, for reasons stated in the Section 2.2 process references are always indirect, through items called <i>elements.</i> Formally a reference to a process is the value of an expression of type <i>element</i>.<br>
…<br>
<i>element</i> values can be stored and retrieved by assignments and references to <i>element</i> variables and by other means.<br>
The language contains a mechanism for making the attributes of a process accessible from the outside, i.e., from within other processes. This is called remote access- ing. A process is thus a referenceable data structure.<br>
</p><p>
It is worth noticing the similarity between a process whose activity body is a dummy statement, and the record concept recently proposed by C. A. R. Hoare and <a href="Niklaus_Wirth" title="Niklaus Wirth">N. Wirth</a></p></blockquote>
<p>Because C++ borrowed <a href="Simula" title="Simula">Simula</a>'s approach to memory allocation—the <i>new</i> keyword when allocating a process/record to obtain a fresh <i>element</i> to that process/record—it is not surprising that C++ eventually resurrected Simula's reference-counted smart-pointer mechanism within <i>element</i> as well.
</p>
<div class="mw-heading mw-heading2"><h2 id="Features">Features</h2></div>
<p>In <a href="C%2B%2B" title="C++">C++</a>, a smart pointer is implemented as a template class that mimics, by means of <a href="Operator_overloading" title="Operator overloading">operator overloading</a>, the behaviors of a traditional <a href="Raw_pointer" class="mw-redirect" title="Raw pointer">(raw) pointer</a>, (e.g. dereferencing, assignment) while providing additional memory management features.
</p><p>Smart pointers can facilitate intentional programming by expressing, in the type, how the memory of the referent of the pointer will be managed. For example, if a C++ function returns a pointer, there is no way to know whether the caller should delete the memory of the referent when the caller is finished with the information.
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">SomeType</span><span class="o">*</span><span class="w"> </span><span class="nf">AmbiguousFunction</span><span class="p">();</span><span class="w"> </span><span class="c1">// What should be done with the result?</span>
</pre></div>
<p>Traditionally, naming conventions have been used to resolve the ambiguity,<sup id="cite_ref-Taligent_6-0" class="reference"><a href="#cite_note-Taligent-6"><span class="cite-bracket">[</span>6<span class="cite-bracket">]</span></a></sup> which is an error-prone, labor-intensive approach. <a href="C%2B%2B11" title="C++11">C++11</a> introduced a way to ensure correct memory management in this case by declaring the function to return a <code>unique_ptr</code>,
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">SomeType</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ObviousFunction</span><span class="p">();</span>
</pre></div>
<p>The declaration of the function return type as a <code>unique_ptr</code> makes explicit the fact that the caller takes ownership of the result, and the C++ runtime ensures that the memory will be reclaimed automatically. Before <a href="C%2B%2B11" title="C++11">C++11</a>, unique_ptr can be replaced with <a href="Auto_ptr" title="Auto ptr">auto_ptr</a>, which is now deprecated.
</p>
<div class="mw-heading mw-heading2"><h2 id="Creating_new_objects">Creating new objects</h2></div><p>
To ease the allocation of a </p><div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="n">SomeType</span><span class="o">&gt;</span>
</pre></div><p><a href="C%2B%2B11" title="C++11">C++11</a> introduced:
</p><div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="k">auto</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">make_shared</span><span class="o">&lt;</span><span class="n">SomeType</span><span class="o">&gt;</span><span class="p">(</span><span class="n">constructor</span><span class="p">,</span><span class="w"> </span><span class="n">parameters</span><span class="p">,</span><span class="w"> </span><span class="n">here</span><span class="p">);</span>
</pre></div><p>
and similarly </p><div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">some_type</span><span class="o">&gt;</span>
</pre></div><p>Since <a href="C%2B%2B14" title="C++14">C++14</a> one can use:
</p><div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="k">auto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">SomeType</span><span class="o">&gt;</span><span class="p">(</span><span class="n">constructor</span><span class="p">,</span><span class="w"> </span><span class="n">parameters</span><span class="p">,</span><span class="w"> </span><span class="n">here</span><span class="p">);</span>
</pre></div>
<p>It is preferred, in almost all circumstances, to use these facilities over the <code>new</code> keyword.<sup id="cite_ref-Sutter_2013_7-0" class="reference"><a href="#cite_note-Sutter_2013-7"><span class="cite-bracket">[</span>7<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="unique_ptr">unique_ptr</h2></div>
<p><a href="C%2B%2B11" title="C++11">C++11</a> introduces <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">std::unique_ptr</code>, defined in the header <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">&lt;memory&gt;</code>.<sup id="cite_ref-ISO14882_2011_8-0" class="reference"><a href="#cite_note-ISO14882_2011-8"><span class="cite-bracket">[</span>8<span class="cite-bracket">]</span></a></sup>
</p><p>A <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">unique_ptr</code> is a container for a raw pointer, which the <code>unique_ptr</code> is said to own. A <code>unique_ptr</code> explicitly prevents copying of its contained pointer (as would happen with normal assignment), but the <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">std::move</code> function can be used to transfer ownership of the contained pointer to another <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">unique_ptr</code>. A <code>unique_ptr</code> cannot be copied because its copy constructor and assignment operators are explicitly deleted.
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p1</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span>
<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">p1</span><span class="p">;</span><span class="w"> </span><span class="c1">// Compile error.</span>
<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">p1</span><span class="p">);</span><span class="w"> </span><span class="c1">// Transfers ownership. p3 now owns the memory and p1 is set to nullptr.</span>

<span class="n">p3</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span><span class="w"> </span><span class="c1">// Deletes the memory.</span>
<span class="n">p1</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span><span class="w"> </span><span class="c1">// Does nothing.</span>
</pre></div>
<p><code>std::<a href="Auto_ptr" title="Auto ptr">auto_ptr</a></code> is <a href="Deprecation" title="Deprecation">deprecated</a> under C++11 and completely removed from <a href="C%2B%2B17" title="C++17">C++17</a>. The copy constructor and assignment operators of <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">auto_ptr</code> do not actually copy the stored pointer. Instead, they <a href="Auto_ptr#Semantics" title="Auto ptr">transfer it</a>, leaving the prior <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">auto_ptr</code> object empty. This was one way to implement strict ownership, so that only one <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">auto_ptr</code> object can own the pointer at any given time. This means that <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">auto_ptr</code> should not be used where copy semantics are needed.<sup id="cite_ref-CERT_9-0" class="reference"><a href="#cite_note-CERT-9"><span class="cite-bracket">[</span>9<span class="cite-bracket">]</span></a></sup> Since <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">auto_ptr</code> already existed with its copy semantics, it could not be upgraded to be a move-only pointer without breaking <a href="Backward_compatibility" title="Backward compatibility">backward compatibility</a> with existing code.
</p>
<div class="mw-heading mw-heading2"><h2 id="shared_ptr_and_weak_ptr">shared_ptr and weak_ptr</h2></div>
<p>C++11 introduces <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">std::shared_ptr</code> and <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">std::weak_ptr</code>, defined in the header <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">&lt;memory&gt;</code>.<sup id="cite_ref-ISO14882_2011_8-1" class="reference"><a href="#cite_note-ISO14882_2011-8"><span class="cite-bracket">[</span>8<span class="cite-bracket">]</span></a></sup> C++11 also introduces <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">std::make_shared</code> (<code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">std::make_unique</code> was introduced in C++14) to safely allocate dynamic memory in the <a href="Resource_acquisition_is_initialization" title="Resource acquisition is initialization">RAII</a> paradigm.<sup id="cite_ref-ISO14882_2014_10-0" class="reference"><a href="#cite_note-ISO14882_2014-10"><span class="cite-bracket">[</span>10<span class="cite-bracket">]</span></a></sup>
</p><p>A <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">shared_ptr</code> is a container for a <a href="Raw_pointer" class="mw-redirect" title="Raw pointer">raw pointer</a>. It maintains <a href="Reference_counting" title="Reference counting">reference counting</a> ownership of its contained pointer in cooperation with all copies of the <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">shared_ptr</code>. An object referenced by the contained raw pointer will be destroyed when and only when all copies of the <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">shared_ptr</code> have been destroyed.
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p0</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span><span class="w"> </span><span class="c1">// Valid, allocates 1 integer and initialize it with value 5.</span>
<span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">[]</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p1</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="p">[</span><span class="mi">5</span><span class="p">]);</span><span class="w"> </span><span class="c1">// Valid, allocates 5 integers.</span>
<span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">[]</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">p1</span><span class="p">;</span><span class="w"> </span><span class="c1">// Both now own the memory.</span>

<span class="n">p1</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span><span class="w"> </span><span class="c1">// Memory still exists, due to p2.</span>
<span class="n">p2</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span><span class="w"> </span><span class="c1">// Frees the memory, since no one else owns the memory.</span>
</pre></div>
<p>A <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">weak_ptr</code> is a container for a raw pointer. It is created as a copy of a <code>shared_ptr</code>. The existence or destruction of <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">weak_ptr</code> copies of a <code>shared_ptr</code> have no effect on the <code>shared_ptr</code> or its other copies. After all copies of a <code>shared_ptr</code> have been destroyed, all <code>weak_ptr</code> copies become empty.
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">make_shared</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">weak_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">wp1</span><span class="w"> </span><span class="p">{</span><span class="n">p1</span><span class="p">};</span><span class="w"> </span><span class="c1">// p1 owns the memory.</span>

<span class="p">{</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">wp1</span><span class="p">.</span><span class="n">lock</span><span class="p">();</span><span class="w"> </span><span class="c1">// Now p1 and p2 own the memory.</span>
<span class="w"> </span><span class="c1">// p2 is initialized from a weak pointer, so you have to check if the</span>
<span class="w"> </span><span class="c1">// memory still exists!</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DoSomethingWith</span><span class="p">(</span><span class="n">p2</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
<span class="c1">// p2 is destroyed. Memory is owned by p1.</span>

<span class="n">p1</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span><span class="w"> </span><span class="c1">// Free the memory.</span>

<span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">p3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">wp1</span><span class="p">.</span><span class="n">lock</span><span class="p">();</span><span class="w"> </span>
<span class="c1">// Memory is gone, so we get an empty shared_ptr.</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p3</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// code will not execute</span>
<span class="w"> </span><span class="n">ActionThatNeedsALivePointer</span><span class="p">(</span><span class="n">p3</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Because the implementation of <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">shared_ptr</code> uses <a href="Reference_counting" title="Reference counting">reference counting</a>, <a href="Reference_count" class="mw-redirect" title="Reference count">circular references</a> are potentially a problem. A circular <code>shared_ptr</code> chain can be broken by changing the code so that one of the references is a <code>weak_ptr</code>.
</p><p>Multiple threads can safely simultaneously access different <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">shared_ptr</code> and <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">weak_ptr</code> objects that point to the same object.<sup id="cite_ref-Boost_11-0" class="reference"><a href="#cite_note-Boost-11"><span class="cite-bracket">[</span>11<span class="cite-bracket">]</span></a></sup>
</p><p>The referenced object must be protected separately to ensure <a href="Thread_safety" title="Thread safety">thread safety</a>.
</p><p><code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">shared_ptr</code> and <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">weak_ptr</code> are based on versions used by the <a href="Boost_(C%2B%2B_libraries)" title="Boost (C++ libraries)">Boost libraries</a>. <a href="C%2B%2B_Technical_Report_1" title="C++ Technical Report 1">C++ Technical Report 1</a> (TR1) first introduced them to the standard, as <a href="C%2B%2B_Technical_Report_1#General_utilities" title="C++ Technical Report 1">general utilities</a>, but C++11 adds more functions, in line with the Boost version.
</p>
<div class="mw-heading mw-heading2"><h2 id="Other_types_of_smart_pointers">Other types of smart pointers</h2></div>
<p>There are other types of smart pointers (which are not in the C++ standard) implemented on popular C++ libraries or custom <a href="Standard_Template_Library" title="Standard Template Library">STL</a>, some examples include <a href="Hazard_pointer" title="Hazard pointer">hazard pointer</a><sup id="cite_ref-12" class="reference"><a href="#cite_note-12"><span class="cite-bracket">[</span>12<span class="cite-bracket">]</span></a></sup> and intrusive pointer.<sup id="cite_ref-13" class="reference"><a href="#cite_note-13"><span class="cite-bracket">[</span>13<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-14" class="reference"><a href="#cite_note-14"><span class="cite-bracket">[</span>14<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div>
<ul><li><a href="Auto_ptr" title="Auto ptr">auto_ptr</a></li>
<li><a href="Fat_pointer" class="mw-redirect" title="Fat pointer">Fat pointer</a></li>
<li><a href="Tagged_pointer" title="Tagged pointer">Tagged pointer</a></li>
<li><a href="Opaque_pointer" title="Opaque pointer">Opaque pointer</a></li>
<li><a href="Reference_(computer_science)" title="Reference (computer science)">Reference (computer science)</a></li>
<li><a href="Boost_(C%2B%2B_libraries)" title="Boost (C++ libraries)">Boost (C++ libraries)</a></li>
<li><a href="Automatic_Reference_Counting" title="Automatic Reference Counting">Automatic Reference Counting</a></li>
<li><a href="Resource_acquisition_is_initialization" title="Resource acquisition is initialization">Resource acquisition is initialization</a> (RAII)</li>
<li><a href="Garbage_collection_(computer_science)" title="Garbage collection (computer science)">Garbage collection</a> in computer programming</li></ul>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */


.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}


/* end https://en.wikipedia.org/ */
</style><div class="reflist">
<div class="mw-references-wrap mw-references-columns"><ol class="references">
<li id="cite_note-Kline_1997-1"><span class="mw-cite-backlink"><b><a href="#cite_ref-Kline_1997_1-0">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */


.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}


/* end https://en.wikipedia.org/ */
</style><cite id="CITEREFKline1997" class="citation web cs1">Kline, Marshall (September 1997). <a rel="nofollow" class="external text" href="http://www.cis.usouthal.edu/faculty/drh/c%2B%2Bfaq/freestore-mgmt.html#%5b16.20">"C++ FAQs Lite's sections on reference-counted smart pointers and copy-on-write reference semantics in the freestore management FAQs"</a>. <i>cis.usouthal.edu</i><span class="reference-accessdate">. Retrieved <span class="nowrap">2018-04-06</span></span>.</cite></span>
</li>
<li id="cite_note-Colvin_1994-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-Colvin_1994_2-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFColvin1994" class="citation web cs1">Colvin, Gregory (1994). <a rel="nofollow" class="external text" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">"proposal to standardize counted_ptr in the C++ standard library"</a> <span class="cs1-format">(PDF)</span>. <i>open-std.org</i><span class="reference-accessdate">. Retrieved <span class="nowrap">2018-04-06</span></span>.</cite></span>
</li>
<li id="cite_note-Klabnik-Nichols_2023-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-Klabnik-Nichols_2023_3-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFKlabnikNichols2023" class="citation book cs1">Klabnik, Steve; Nichols, Carol (2023) [2018]. "15. Smart Pointers". <i>The Rust Programming Language</i> (2&nbsp;ed.). San Francisco, California, USA: <a href="No_Starch_Press%2C_Inc." class="mw-redirect" title="No Starch Press, Inc.">No Starch Press, Inc.</a> pp.&nbsp;<span class="nowrap">315–</span>351. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a>&nbsp;<bdi>978-1-7185-0310-6</bdi>.</cite> (xxix+1+527+3 pages)</span>
</li>
<li id="cite_note-Stroustrup-4"><span class="mw-cite-backlink"><b><a href="#cite_ref-Stroustrup_4-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFStroustrup" class="citation web cs1">Stroustrup, Bjarne. <a rel="nofollow" class="external text" href="http://www.stroustrup.com/hopl2.pdf">"A history of C++: 1979–1991"</a> <span class="cs1-format">(PDF)</span><span class="reference-accessdate">. Retrieved <span class="nowrap">2018-04-06</span></span>.</cite></span>
</li>
<li id="cite_note-Dahl-Nygaard_1966-5"><span class="mw-cite-backlink"><b><a href="#cite_ref-Dahl-Nygaard_1966_5-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFDahlNygaard1966" class="citation web cs1">Dahl, Ole-Johan; Nygaard, Kristen (September 1966). <a rel="nofollow" class="external text" href="http://folk.uio.no/simula67/Archive/artikkel1966cacm.pdf">"SIMULA—An ALGOL-based simulation language"</a> <span class="cs1-format">(PDF)</span>. <i>folk.uio.no</i><span class="reference-accessdate">. Retrieved <span class="nowrap">2018-04-06</span></span>.</cite></span>
</li>
<li id="cite_note-Taligent-6"><span class="mw-cite-backlink"><b><a href="#cite_ref-Taligent_6-0">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://root.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_67.html#HEADING81">"Taligent's Guide to Designing Programs, section Use special names for copy, create, and adopt routines"</a>.</cite></span>
</li>
<li id="cite_note-Sutter_2013-7"><span class="mw-cite-backlink"><b><a href="#cite_ref-Sutter_2013_7-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFSutter2013" class="citation web cs1"><a href="Herb_Sutter" title="Herb Sutter">Sutter, Herb</a> (2013-04-20). <a rel="nofollow" class="external text" href="http://isocpp.org/blog/2013/04/trip-report-iso-c-spring-2013-meeting">"Trip Report: ISO C++ Spring 2013 Meeting"</a>. <i>isocpp.org</i><span class="reference-accessdate">. Retrieved <span class="nowrap">2013-06-14</span></span>.</cite></span>
</li>
<li id="cite_note-ISO14882_2011-8"><span class="mw-cite-backlink">^ <a href="#cite_ref-ISO14882_2011_8-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-ISO14882_2011_8-1"><sup><i><b>b</b></i></sup></a></span> <span class="reference-text">ISO&nbsp;14882:2011 20.7.1</span>
</li>
<li id="cite_note-CERT-9"><span class="mw-cite-backlink"><b><a href="#cite_ref-CERT_9-0">^</a></b></span> <span class="reference-text">CERT C++ Secure Coding Standard</span>
</li>
<li id="cite_note-ISO14882_2014-10"><span class="mw-cite-backlink"><b><a href="#cite_ref-ISO14882_2014_10-0">^</a></b></span> <span class="reference-text">ISO&nbsp;14882:2014 20.7.1</span>
</li>
<li id="cite_note-Boost-11"><span class="mw-cite-backlink"><b><a href="#cite_ref-Boost_11-0">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm#ThreadSafety">"boost::shared_ptr thread safety"</a>.</cite> (NB. Does not formally cover std::shared_ptr, but is believed to have the same threading limitations.)</span>
</li>
<li id="cite_note-12"><span class="mw-cite-backlink"><b><a href="#cite_ref-12">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://github.com/facebook/folly/blob/main/folly/synchronization/Hazptr.h">"folly/Hazptr.h at main · facebook/folly"</a>. <i>github.com</i>.</cite></span>
</li>
<li id="cite_note-13"><span class="mw-cite-backlink"><b><a href="#cite_ref-13">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://www.boost.org/doc/libs/1_81_0/libs/smart_ptr/doc/html/smart_ptr.html">"Boost.SmartPtr: The Smart Pointer Library - 1.81.0"</a>. <i>boost.org</i>.</cite></span>
</li>
<li id="cite_note-14"><span class="mw-cite-backlink"><b><a href="#cite_ref-14">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://github.com/electronicarts/EASTL/blob/master/include/EASTL/intrusive_ptr.h">"EASTL/intrusive_ptr.h at master · electronicarts/EASTL"</a>. <i>github.com</i>.</cite></span>
</li>
</ol></div></div>
<div class="mw-heading mw-heading2"><h2 id="Further_reading">Further reading</h2></div>
<ul><li><cite id="CITEREFMeyers2014" class="citation book cs1"><a href="Scott_Meyers" title="Scott Meyers">Meyers, Scott</a> (2014). <i>Effective Modern C++</i>. Sebastopol, California, USA: <a href="O'Reilly_Media" title="O'Reilly Media">O'Reilly Media</a>. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a>&nbsp;<bdi>978-1-49190399-5</bdi>. <a href="OCLC_(identifier)" class="mw-redirect" title="OCLC (identifier)">OCLC</a>&nbsp;<a rel="nofollow" class="external text" href="https://search.worldcat.org/oclc/884480640">884480640</a>.</cite></li>
<li><cite id="CITEREFAlexandrescu2001" class="citation book cs1"><a href="Andrei_Alexandrescu" title="Andrei Alexandrescu">Alexandrescu, Andrei</a> (2001). <a rel="nofollow" class="external text" href="http://www.informit.com/articles/article.aspx?p=25264">"Smart Pointers"</a>. <a href="Modern_C%2B%2B_Design" title="Modern C++ Design"><i>Modern C++ Design - Generic Programming and Design Patterns Applied</i></a>. <a href="Addison-Wesley" title="Addison-Wesley">Addison-Wesley</a>.</cite></li>
<li><cite id="CITEREFSutter2002" class="citation web cs1"><a href="Herb_Sutter" title="Herb Sutter">Sutter, Herb</a> (2002-08-01). <a rel="nofollow" class="external text" href="http://www.drdobbs.com/184403837/">"The New C++: Smart(er) Pointers"</a>.</cite></li>
<li><a rel="nofollow" class="external text" href="http://ootips.org/yonat/4dev/smart-pointers.html">Smart Pointers - What, Why, Which?</a>. Yonat Sharon</li>
<li><a rel="nofollow" class="external text" href="http://dlugosz.com/Repertoire/refman/Classics/Smart%20Pointers%20Overview.html">Smart Pointers Overview</a>. John M. Dlugosz</li></ul>
<div class="mw-heading mw-heading2"><h2 id="External_links">External links</h2></div>
<ul><li><a rel="nofollow" class="external text" href="http://www.josuttis.com/libbook/cont/countptr.hpp.html">countptr.hpp</a>. <i><a rel="nofollow" class="external text" href="http://www.josuttis.com/libbook/">The C++ Standard Library - A Tutorial and Reference</a></i> by Nicolai M. Josuttis</li>
<li><a rel="nofollow" class="external text" href="http://boost.org/libs/smart_ptr/smart_ptr.htm">Boost Smart Pointers</a></li>
<li><a rel="nofollow" class="external text" href="http://barrkel.blogspot.com/2008/09/smart-pointers-in-delphi.html">Smart Pointers in Delphi</a></li>
<li><a rel="nofollow" class="external text" href="https://doc.rust-lang.org/book/ch15-00-smart-pointers.html">Smart Pointers in Rust</a></li>
<li><a rel="nofollow" class="external text" href="http://quant-coder.blogspot.com/2015/12/built-in-smart-pointers-in-modern-c.html">Smart Pointers in Modern C++</a></li></ul></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-05-20" href="https://en.wikipedia.org/wiki/?title=Smart_pointer&amp;oldid=1291274757">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>

</body></html>